<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>InnoDB 行锁机制深度解析</title>
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background-color: #f8fafc;
            color: #1e293b;
            line-height: 1.6;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 700;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-4px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .drop-cap::first-letter {
            float: left;
            font-size: 3.5rem;
            line-height: 0.8;
            margin: 0.15em 0.1em 0 0;
            color: #1d4ed8;
            font-weight: 700;
        }
        .tooltip {
            position: relative;
            border-bottom: 1px dotted #3b82f6;
            cursor: help;
        }
        .tooltip:hover::after {
            content: attr(data-tooltip);
            position: absolute;
            left: 50%;
            transform: translateX(-50%);
            bottom: 100%;
            background: #1e293b;
            color: white;
            padding: 0.5rem 1rem;
            border-radius: 0.5rem;
            font-size: 0.875rem;
            white-space: nowrap;
            z-index: 10;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4 sm:px-6 lg:px-8">
        <div class="max-w-5xl mx-auto">
            <div class="flex flex-col md:flex-row items-center">
                <div class="md:w-2/3 mb-10 md:mb-0">
                    <h1 class="text-4xl md:text-5xl font-bold leading-tight mb-4">InnoDB 行锁机制</h1>
                    <p class="text-xl md:text-2xl opacity-90 mb-6">深入解析数据库并发控制的精髓</p>
                    <p class="text-lg opacity-80 max-w-2xl">通过基于索引的行锁、间隙锁、意向锁等机制，InnoDB 实现了高效的行级锁定，平衡了并发性能和数据一致性的需求。</p>
                </div>
                <div class="md:w-1/3 flex justify-center">
                    <div class="relative w-64 h-64">
                        <div class="absolute inset-0 bg-blue-500 rounded-full opacity-20 animate-pulse"></div>
                        <div class="absolute inset-4 bg-blue-600 rounded-full opacity-30 animate-pulse delay-100"></div>
                        <div class="absolute inset-8 bg-blue-700 rounded-full opacity-40 animate-pulse delay-200"></div>
                        <div class="absolute inset-12 bg-blue-800 rounded-full flex items-center justify-center">
                            <i class="fas fa-lock text-4xl text-white"></i>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="max-w-5xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
        <!-- Introduction -->
        <section class="mb-16">
            <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                <div class="p-8">
                    <div class="drop-cap">
                        <p>InnoDB 的行锁机制是为了提高数据库的并发性能和数据一致性而设计的。通过使用基于索引的行锁、间隙锁、意向锁等机制，InnoDB 实现了高效的行级锁定。然而，行锁的实现也需要处理锁争用和死锁等问题，这些问题需要通过优化锁的管理和事务隔离策略来加以解决。</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Lock Types -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 flex items-center">
                <i class="fas fa-key mr-3 text-blue-600"></i>
                锁的基本概念与类型
            </h2>
            
            <div class="grid md:grid-cols-2 gap-8">
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                    <div class="p-8">
                        <h3 class="text-xl font-bold mb-4 text-blue-800">行锁 (Row Lock)</h3>
                        <p class="text-gray-700 mb-4">InnoDB 的行锁是一种<span class="font-semibold text-blue-600">细粒度锁</span>，用于锁定表中的某一行数据，以允许多个事务并行处理不同的数据行，减少锁争用和提高并发性能。</p>
                        <div class="bg-blue-50 p-4 rounded-lg">
                            <p class="text-sm text-blue-800"><i class="fas fa-info-circle mr-2"></i>行锁依赖于索引实现，对非索引字段的查询会导致全表扫描，可能引发表锁。</p>
                        </div>
                    </div>
                </div>
                
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                    <div class="p-8">
                        <h3 class="text-xl font-bold mb-4 text-blue-800">锁的类型</h3>
                        <ul class="space-y-3">
                            <li class="flex items-start">
                                <i class="fas fa-lock-open text-green-500 mt-1 mr-3"></i>
                                <div>
                                    <span class="font-semibold">共享锁 (S Lock)</span>
                                    <p class="text-gray-700 text-sm">允许事务对数据行进行读取操作，但不能修改。</p>
                                </div>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-lock text-red-500 mt-1 mr-3"></i>
                                <div>
                                    <span class="font-semibold">排他锁 (X Lock)</span>
                                    <p class="text-gray-700 text-sm">允许事务对数据行进行读取和修改操作，会阻止其他事务对同一行的任何操作。</p>
                                </div>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>

        <!-- Implementation Details -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 flex items-center">
                <i class="fas fa-cogs mr-3 text-blue-600"></i>
                实现机制与细节
            </h2>
            
            <div class="grid md:grid-cols-3 gap-8">
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                    <div class="p-8">
                        <h3 class="text-xl font-bold mb-4 text-blue-800 flex items-center">
                            <i class="fas fa-project-diagram mr-2"></i>
                            锁定结构
                        </h3>
                        <p class="text-gray-700 mb-3">InnoDB 使用 <code class="bg-gray-100 px-2 py-1 rounded">trx_id</code>（事务ID）和 <code class="bg-gray-100 px-2 py-1 rounded">lock_id</code>（锁ID）来管理锁。</p>
                        <p class="text-gray-700">每个事务在对某行数据进行操作时，会在数据行上设置锁标记，并记录该锁的事务ID。</p>
                    </div>
                </div>
                
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                    <div class="p-8">
                        <h3 class="text-xl font-bold mb-4 text-blue-800 flex items-center">
                            <i class="fas fa-database mr-2"></i>
                            锁的记录
                        </h3>
                        <p class="text-gray-700">InnoDB 在<strong>锁表</strong>（<code class="bg-gray-100 px-2 py-1 rounded">INNODB_LOCKS</code>）中维护当前的锁信息，并记录每个锁所关联的事务。锁表通过 <code class="bg-gray-100 px-2 py-1 rounded">trx_id</code> 和 <code class="bg-gray-100 px-2 py-1 rounded">lock_id</code> 进行索引。</p>
                    </div>
                </div>
                
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                    <div class="p-8">
                        <h3 class="text-xl font-bold mb-4 text-blue-800 flex items-center">
                            <i class="fas fa-sitemap mr-2"></i>
                            索引与锁
                        </h3>
                        <p class="text-gray-700">InnoDB 主要依赖于索引来实现行锁。锁定行数据时，InnoDB 会先定位到相关的索引页，然后对相应的行记录加锁。</p>
                    </div>
                </div>
            </div>
            
            <div class="mt-8 grid md:grid-cols-2 gap-8">
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                    <div class="p-8">
                        <h3 class="text-xl font-bold mb-4 text-blue-800 flex items-center">
                            <i class="fas fa-grip-lines mr-2"></i>
                            Gap Lock (间隙锁)
                        </h3>
                        <p class="text-gray-700 mb-3">为了避免<span class="tooltip" data-tooltip="幻读指事务执行过程中看到的数据行数不一致的情况">幻读</span>，InnoDB 使用了间隙锁（Gap Lock）机制。</p>
                        <p class="text-gray-700">Gap Lock 锁定了索引中记录之间的间隙，防止其他事务在这些间隙中插入新的记录。</p>
                    </div>
                </div>
                
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                    <div class="p-8">
                        <h3 class="text-xl font-bold mb-4 text-blue-800 flex items-center">
                            <i class="fas fa-list-ol mr-2"></i>
                            Record Lock (记录锁)
                        </h3>
                        <p class="text-gray-700">行锁本身就是记录锁（Record Lock），它锁定的是索引中的具体数据行。对于正在进行操作的记录，InnoDB 会加排他锁以确保一致性。</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Lock Strategy -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 flex items-center">
                <i class="fas fa-chess mr-3 text-blue-600"></i>
                锁定策略
            </h2>
            
            <div class="grid md:grid-cols-2 gap-8">
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                    <div class="p-8">
                        <h3 class="text-xl font-bold mb-4 text-blue-800">意向锁 (Intention Lock)</h3>
                        <p class="text-gray-700 mb-3">为了提高锁的效率和避免死锁，InnoDB 采用了意向锁的机制。</p>
                        <p class="text-gray-700">意向锁是<span class="font-semibold">表级锁</span>，它用于标记事务打算对某些行加锁，从而在实际加锁时减少锁冲突。</p>
                    </div>
                </div>
                
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                    <div class="p-8">
                        <h3 class="text-xl font-bold mb-4 text-blue-800">锁的兼容性</h3>
                        <div class="mermaid">
                            graph LR
                                A[共享锁(S)] -->|兼容| A
                                A -->|不兼容| B[排他锁(X)]
                                B -->|不兼容| A
                                B -->|不兼容| B
                        </div>
                        <p class="text-gray-700 mt-4">InnoDB 支持锁的兼容性控制，多个事务可以对同一行数据加共享锁，但只有一个事务可以加排他锁。</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Deadlock & Performance -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 flex items-center">
                <i class="fas fa-skull-crossbones mr-3 text-blue-600"></i>
                死锁检测与性能考量
            </h2>
            
            <div class="grid md:grid-cols-2 gap-8">
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                    <div class="p-8">
                        <h3 class="text-xl font-bold mb-4 text-blue-800">死锁检测算法</h3>
                        <p class="text-gray-700 mb-3">InnoDB 使用了基于图的<span class="font-semibold">死锁检测算法</span>来检测和处理死锁。</p>
                        <p class="text-gray-700">系统会构建一个等待图（Wait-for Graph），并通过检测图中的循环来识别死锁。当发现死锁时，InnoDB 会选择一个事务作为牺牲者，并回滚其操作以解除死锁。</p>
                    </div>
                </div>
                
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover">
                    <div class="p-8">
                        <h3 class="text-xl font-bold mb-4 text-blue-800">行锁的性能考量</h3>
                        <ul class="space-y-3">
                            <li class="flex items-start">
                                <i class="fas fa-tachometer-alt text-yellow-500 mt-1 mr-3"></i>
                                <div>
                                    <span class="font-semibold">锁争用</span>
                                    <p class="text-gray-700 text-sm">虽然行锁减少了锁的粒度，但在高并发环境下，锁争用仍然是一个重要的性能瓶颈。</p>
                                </div>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-layer-group text-purple-500 mt-1 mr-3"></i>
                                <div>
                                    <span class="font-semibold">事务隔离级别</span>
                                    <p class="text-gray-700 text-sm">InnoDB 支持多种事务隔离级别（如读已提交、可重复读），这些隔离级别对行锁的行为有重要影响。</p>
                                </div>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>

        <!-- Visualization -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 flex items-center">
                <i class="fas fa-chart-network mr-3 text-blue-600"></i>
                InnoDB 锁机制关系图谱
            </h2>
            
            <div class="bg-white rounded-xl shadow-md overflow-hidden">
                <div class="p-8">
                    <div class="mermaid">
                        graph TD
                            A[InnoDB 行锁机制] --> B[锁类型]
                            A --> C[实现机制]
                            A --> D[锁定策略]
                            A --> E[死锁处理]
                            
                            B --> B1[共享锁(S)]
                            B --> B2[排他锁(X)]
                            
                            C --> C1[锁定结构]
                            C --> C2[锁的记录]
                            C --> C3[索引与锁]
                            C --> C4[Gap Lock]
                            C --> C5[Record Lock]
                            
                            D --> D1[意向锁]
                            D --> D2[锁兼容性]
                            
                            E --> E1[等待图检测]
                            E --> E2[事务回滚]
                            
                            style A fill:#1d4ed8,color:#fff,stroke:#1d4ed8
                            style B fill:#3b82f6,color:#fff
                            style C fill:#3b82f6,color:#fff
                            style D fill:#3b82f6,color:#fff
                            style E fill:#3b82f6,color:#fff
                            
                            style B1 fill:#10b981,color:#fff
                            style B2 fill:#ef4444,color:#fff
                    </div>
                </div>
            </div>
        </section>
    </main>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            },
            securityLevel: 'loose'
        });
        
        // 平滑滚动
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                document.querySelector(this.getAttribute('href')).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });
    </script>
</body>
</html>